<template>
    <div class="catapult-menu">
        <div @click="toggleMenu" class="mask" :style="{width:adaption(width)+'px',background:menuBg,height:adaption(width)+'px',...menuHomePosition,transform:menuHomeTransform,...maskTransform}"></div>
        <div class="menu-container" ref="menuHome" @click="toggleMenu"
             :style="{width:adaption(width)+'px',background:menuBg,height:adaption(width)+'px',...menuHomePosition,transform:menuHomeTransform}">
            <img :src="menuSrc" v-if="menuSrc">
            <!-- 主按钮插槽 -->
            <slot name="main"></slot>
        </div>
        <div class="menu-item" v-for="(item,index) in menuItems" :id="item.name" @click="clickMenu(item,index)"
             :style="{width:adaption(width*.8)+'px',background:itemBg,height:adaption(width*.8)+'px',...menuItemPosition[index],...menuHomeItemTransformList[index]}">
            <img :src="item.src" v-if="item.src">
            <span :class="item.class" v-else-if="item.class"></span>
            <slot :name="item.name" v-else-if="item.name"></slot>
        </div>
    </div>
</template>

<script lang="ts">
    import {Component, Prop, Vue, Watch, Emit} from "vue-property-decorator";

    @Component({components: {}})
    //弹射器菜单
    export default class CatapultMenu extends Vue {
        //图片地址也可以是base64码
        @Prop({type: String, default: ""})
        private menuSrc!: string;

        //按钮位置[LT：左上；RT：右上；LB：左下；RB：右下]
        @Prop({type: String, default: "LT"})
        private position!: string;

        //按钮宽度，相对375px的宽度，会根据屏幕宽度做自适应
        @Prop({type: Number, default: 50})
        private width!: number;

        //展开距离，相对375px的宽度，会根据屏幕宽度做自适应
        @Prop({type: Number, default: 150})
        private baseDistance!: number;

        //大按钮背景色，可以是具体颜色也可以是hash
        @Prop({type: String, default: "white"})
        private menuBg!: string;

        //小按钮背景色，可以是具体颜色也可以是hash
        @Prop({type: String, default: "white"})
        private itemBg!: string;

        //按钮数据[{src: String,class:String,...[arg]},...]
        @Prop({type: Array, default: []})
        private menuItems!: any[];

        private openFlag: boolean = false;
        private operators: string[] = ["+", "+"];
        private menuHomeTransform: string = "rotate(0deg)";
        private menuHomeItemTransformList: any[] = [];
        private maskTransform: any = {};


        private adaption(size: number): number {
            return (size / 375) * document.body.clientWidth;
        }

        @Watch("openFlag")
        private onChangeOpenFlag(n: boolean) {
            if (n) {
                this.maskTransform = {left: 0, right: 0, top: 0, bottom: 0, width: "100vw", height: "100vh", transform: "rotate(0)", zIndex: 201};
                this.open();
            } else {
                this.maskTransform = {};
                this.close();
            }
        }

        private get menuItemPosition(): any[] {
            let menuItemPosition: any[] = [];
            switch (this.position) {
                case "LT":
                    this.menuItems.forEach((item: any) => {
                        menuItemPosition.push({left: this.adaption(26) + "px", top: this.adaption(26) + "px"});
                    });
                    break;
                case "RT":
                    this.menuItems.forEach((item: any) => {
                        menuItemPosition.push({right: this.adaption(26) + "px", top: this.adaption(26) + "px"});
                    });
                    break;
                case "LB":
                    this.menuItems.forEach((item: any) => {
                        menuItemPosition.push({left: this.adaption(26) + "px", bottom: this.adaption(26) + "px"});
                    });
                    break;
                case "RB":
                    this.menuItems.forEach((item: any) => {
                        menuItemPosition.push({right: this.adaption(26) + "px", bottom: this.adaption(26) + "px"});
                    });
                    break;
                default:
                    this.menuItems.forEach((item: any) => {
                        menuItemPosition.push({left: this.adaption(26) + "px", top: this.adaption(26) + "px"});
                    });
                    break;
            }

            return menuItemPosition;
        };

        private get menuHomePosition(): any {
            const menuHomePosition: any = {};

            switch (this.position) {
                case "LT":
                    menuHomePosition.left = this.adaption(20) + "px";
                    menuHomePosition.top = this.adaption(20) + "px";
                    this.operators = ["+", "+"];
                    break;
                case "RT":
                    menuHomePosition.right = this.adaption(20) + "px";
                    menuHomePosition.top = this.adaption(20) + "px";
                    this.operators = ["-", "+"];
                    break;
                case "LB":
                    menuHomePosition.left = this.adaption(20) + "px";
                    menuHomePosition.bottom = this.adaption(20) + "px";
                    this.operators = ["+", "-"];
                    break;
                case "RB":
                    menuHomePosition.right = this.adaption(20) + "px";
                    menuHomePosition.bottom = this.adaption(20) + "px";
                    this.operators = ["-", "-"];
                    break;
                default:
                    menuHomePosition.left = this.adaption(20) + "px";
                    menuHomePosition.top = this.adaption(20) + "px";
                    this.operators = ["+", "+"];
                    break;
            }

            return menuHomePosition;
        }

        private toggleMenu() {
            if (!this.openFlag) {
                this.menuItems.forEach((item, index) => {
                    this.toggleMenuTransition(index, false);
                });
                this.menuHomeTransform = "rotate(360deg)";
            } else {
                this.menuItems.forEach((item, index) => {
                    this.toggleMenuTransition(index, true);
                });
                this.menuHomeTransform = "rotate(0)";

            }
            this.openFlag = !this.openFlag;
        }

        private toggleMenuTransition(index: number, revert: boolean) {
            let oneArea = 90 / (this.menuItems.length - 1);
            let axisX = Math.sin((this.menuItems.length - 1 - index) * oneArea * 2 * Math.PI / 360);
            let axisY = Math.cos((this.menuItems.length - 1 - index) * oneArea * 2 * Math.PI / 360);
            if (!revert) {
                setTimeout(() => {
                    this.$set(this.menuHomeItemTransformList, index, {
                        transitionDuration: "200ms",
                        transform: `translate(${this.operators[0]}${this.adaption(this.baseDistance) * axisX}px,${this.operators[1]}${this.baseDistance * axisY}px) rotate(360deg)`
                    });
                }, index * 100);
            } else {
                setTimeout(() => {
                    this.$set(this.menuHomeItemTransformList, index, {
                        transitionDuration: "200ms",
                        transform: "translate(0,0) rotate(0)"
                    });
                }, (this.menuItems.length - index - 1) * 100);
            }
        }

        //点击 小按钮的触发事件 触发事件
        //@arg index：按钮数据下标，item:按钮对象
        @Emit("clickMenu")
        private clickMenu(item: any, index: number) {
            this.toggleMenu();
        }

        //小按钮展开 触发事件
        @Emit("openMenu")
        private open() {

        }

        //小按钮关闭 触发事件
        @Emit("closeMenu")
        private close() {

        }
    }
</script>

<style scoped lang="stylus">
    .menu-container
        overflow hidden;
        width 50px;
        height 50px;
        position absolute;
        display flex;
        justify-content center;
        align-items center;
        z-index 210;
        border-radius 50%;
        transition-duration 400ms;
        border 1px solid #ddd;

    .menu-item
        position absolute;
        border-radius 50%;
        z-index 209;
        display flex;
        justify-content center;
        align-items center;
        border 1px solid #ddd;

    img
        width 50%;

    .mask
        background rgba(0, 0, 0, .3) !important;
        width 50px;
        height 50px;
        position absolute;
        /*transition all .4s;*/
        z-index -1;
        left auto;
        right auto;
        top auto;
        bottom auto;

    .catapult-menu
        z-index 250;

</style>